import React, {useRef} from 'react';
import {
  GestureResponderEvent,
  NativeSyntheticEvent,
  TargetedEvent,
  View,
  Animated,
} from 'react-native';
import styled from 'styled-components/native';

const TouchableOpacityContainer = styled.TouchableOpacity<{
  focused?: boolean;
  disabled?: boolean;
  width?: number;
  radius?: number;
  ani?: boolean;
  shadow?: boolean;
}>`
  border: ${props => ('width' in props ? props.width : 4)}px solid
    ${props => (props.focused ? 'rgba(255,255,255,0.5)' : 'transparent')};
  border-radius: ${({radius = 0}) => (radius ? `${radius + 8}px` : '0px')};
  overflow: hidden;
  elevation: ${props => (props.focused && props.shadow ? 6 : 0)};
  box-shadow: ${props =>
    props.focused && props.shadow
      ? '6px 6px 6px rgba(0, 0, 0, 0.5)'
      : '0px 0px 0px rgba(0, 0, 0, 0)'};
  background: ${props =>
    props.focused && props.width === 0 ? 'rgba(0, 0, 0, 0.4)' : 'transparent'};
`;

interface Props {
  onBlur?: ((e: NativeSyntheticEvent<TargetedEvent>) => void) | undefined;
  onPress?: ((event: GestureResponderEvent) => void) | undefined;
  onFocus?: ((e: NativeSyntheticEvent<TargetedEvent>) => void) | undefined;
  width?: number;
  radius?: number;
  style?: any;
  ani?: boolean;
  shadow?: boolean;
}

class FocusableHighlight extends React.Component<Props> {
  state = {
    focused: false,
  };

  render() {
    const {
      radius = 0,
      width = 4,
      ani = false,
      shadow = true,
      style,
      ...props
    } = this.props;
    return (
      <TouchableOpacityContainer
        activeOpacity={0.8}
        radius={radius}
        width={width}
        shadow={shadow}
        focused={this.state.focused}
        ani={ani}
        onPress={(event: GestureResponderEvent) => {
          if (props.onPress && event.preventDefault) {
            props.onPress(event);
          }
        }}
        style={style}
        onFocus={event => {
          this.setState({
            focused: true,
          });
          if (props.onFocus) {
            props.onFocus(event);
          }
        }}
        onBlur={event => {
          this.setState({
            focused: false,
          });
          if (props.onBlur) {
            props.onBlur(event);
          }
        }}>
        {props.children || <View />}
      </TouchableOpacityContainer>
    );
  }
}
const FocusableHighlightAnimated =
  Animated.createAnimatedComponent(FocusableHighlight);

const FocusableHighlightWithAnimated: React.FC<
  Props & {
    ani?: boolean;
  }
> = ({children, ...props}) => {
  const spinValue = useRef<any>(new Animated.Value(1));
  const fanim: any = useRef<any>(
    Animated.timing(spinValue.current, {
      toValue: 1.03,
      duration: 300,
      useNativeDriver: true,
      isInteraction: false,
    }),
  ).current;

  const banim: any = useRef<any>(
    Animated.timing(spinValue.current, {
      toValue: 1,
      duration: 300,
      useNativeDriver: true,
      isInteraction: false,
    }),
  ).current;

  return (
    <FocusableHighlightAnimated
      {...props}
      style={{
        ...(props.style || {}),
        transform: [{scale: spinValue.current}],
      }}
      onFocus={event => {
        if (props.ani) {
          fanim.start();
        }
        if (props.onFocus) {
          props.onFocus(event);
        }
      }}
      onBlur={event => {
        if (props.ani) {
          banim.start();
        }
        if (props.onBlur) {
          props.onBlur(event);
        }
      }}>
      {children}
    </FocusableHighlightAnimated>
  );
};

export default FocusableHighlightWithAnimated;
